import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap;

import static java.lang.System.exit;

public class Methods {
    char[] inputProgram;
    int inputPointer;
    IdentifierTable identifierTable = new IdentifierTable();
    MiddleCodeTable codeTable = new MiddleCodeTable();
    TempVarTable tempVarTable = new TempVarTable();
    TwoTuple word = new TwoTuple("", "");       //读头

    HashMap<String, String> ConstTable = new HashMap<String, String>();

    StringBuilder pre = new StringBuilder("");              //前缀标识
    StringBuilder output = new StringBuilder("");          // debug输出
    String output1;          // out输出

    // 添加间隔符 "-"
    void addPre() {
        pre.append("-");
    }

    // 删除最后一个字符
    void popPre() {
        pre.deleteCharAt(pre.length() - 1);
    }

    public Methods(char[] inputProgram, int inputPointer) {
        this.inputProgram = inputProgram;
        this.inputPointer = inputPointer;
    }

    public TwoTuple nextInput(char[] inputProgram) throws IOException {
        StringBuilder temp = new StringBuilder("");
        int state = 0;
        char symbol;

        while (inputProgram[inputPointer] != '#') {
            symbol = inputProgram[inputPointer];
            // 遇到空格跳过
            if (symbol == ' ') {
                this.inputPointer++;
                continue;
            }
            if (state == 0) {
                if (symbol >= 'a' && symbol <= 'z') {
                    if (symbol == 's') {
                        state = 201;
                        temp.append(symbol);
                        this.inputPointer++;
                        continue;
                    }
                    if (symbol == 'e') {
                        state = 501;
                        temp.append(symbol);
                        this.inputPointer++;
                        continue;
                    }
                    if (symbol == 'i') {
                        state = 401;
                        temp.append(symbol);
                        this.inputPointer++;
                        continue;
                    }
                    if (symbol == 'd') {
                        state = 1001;
                        temp.append(symbol);
                        this.inputPointer++;
                        continue;
                    }
                    if (symbol == 'w') {

                        state = 1101;
                        temp.append(symbol);
                        this.inputPointer++;
                        continue;
                    }

                    state = 1;
                    temp.append(symbol);
                    this.inputPointer++;
                    continue;
                }
                if (symbol >= '0' && symbol <= '9') {
                    state = 1301;
                    temp.append(symbol);
                    this.inputPointer++;
                    return new TwoTuple("数字", temp.toString());
                }

                if (symbol == '"') {
                    if (!isExistMark(inputPointer)) { //判断是否有对应的引号
                        inputPointer++;
                        continue;
                    }
                    state = 701;
                    temp.append(symbol);
                    this.inputPointer++;
                    continue;
                }
                if (symbol == '<') {
                    state = 801;
                    temp.append(symbol);
                    this.inputPointer++;
                    continue;
                }
                if (symbol == '=') {
                    state = 901;
                    temp.append(symbol);
                    this.inputPointer++;
                    continue;
                }
                if (symbol == '>') {
                    state = 1201;
                    temp.append(symbol);
                    this.inputPointer++;
                    continue;
                }
                if (symbol == ';') {
                    temp.append(symbol);
                    this.inputPointer++;
                    return new TwoTuple("分号", temp.toString());
                }
                if (symbol == ',') {
                    temp.append(symbol);
                    this.inputPointer++;
                    return new TwoTuple("逗号", temp.toString());
                }
                if (symbol == '+') {
                    temp.append(symbol);
                    this.inputPointer++;
                    return new TwoTuple("连接运算符", temp.toString());
                }
                if (symbol == '*') {
                    temp.append(symbol);
                    this.inputPointer++;
                    return new TwoTuple("重复运算符", temp.toString());
                }
                if (symbol == '(') {
                    temp.append(symbol);
                    this.inputPointer++;
                    return new TwoTuple("左括号", temp.toString());
                }
                if (symbol == ')') {
                    temp.append(symbol);
                    this.inputPointer++;
                    return new TwoTuple("右括号", temp.toString());
                }
            }
            //标识符
            if (state == 1) {

                if (symbol >= 'a' && symbol <= 'z') {
                    temp.append(symbol);
                    this.inputPointer++;
                    continue;
                }
                if (symbol >= '0' && symbol <= '9') {
                    temp.append(symbol);
                    this.inputPointer++;
                    continue;
                }
                //addItable(tempWord); // 添加到标识符表
                return new TwoTuple("标识符", temp.toString());
            }
            //数字
            if (state == 1301) {

                if (symbol >= '0' && symbol <= '9') {
                    temp.append(symbol);
                    this.inputPointer++;
                    continue;
                }
                return new TwoTuple("数字", temp.toString());
            }
            if (state == 701) { //"

                if (symbol >= 'a' && symbol <= 'z') {
                    state = 701;
                    temp.append(symbol);
                    this.inputPointer++;
                    continue;
                }
                state = 702;
                continue;
            }
            if (state == 702) {

                if (symbol == '"') {
                    temp.append(symbol);
                    this.inputPointer++;
                    return new TwoTuple("字符串", temp.toString());
                }
                state = 8080;
                continue;
            }
            //找到错误字符串的引号并返回错误信息
            if (state == 8080) {

                if (symbol != '"') {
                    temp.append(symbol);
                    this.inputPointer++;
                    continue;
                }

                // 使用setLength方法清空
                temp.setLength(0);
                state = 0;
                inputPointer++;

                return new TwoTuple("Error of type", "Not String");
            }
            // 识别 "<"
            if (state == 801) {
                // 识别 "<>"
                if (symbol == '>') {
                    temp.append(symbol);
                    this.inputPointer++;
                    return new TwoTuple("关系运算符", temp.toString());
                }
                // 识别 "<="
                if (symbol == '=') {
                    temp.append(symbol);
                    this.inputPointer++;
                    return new TwoTuple("关系运算符", temp.toString());
                }
                // 识别 "<"
                return new TwoTuple("关系运算符", temp.toString());
            }

            // 识别 ">"
            if (state == 1201) {
                // 识别 ">="
                if (symbol == '=') {
                    temp.append(symbol);
                    this.inputPointer++;
                    return new TwoTuple("关系运算符", temp.toString());
                }

                return new TwoTuple("关系运算符", temp.toString());
            }
            // 识别 "="
            if (state == 901) {
                // 识别 "=="
                if (symbol == '=') {
                    temp.append(symbol);
                    this.inputPointer++;
                    return new TwoTuple("关系运算符", temp.toString());
                }

                return new TwoTuple("=", temp.toString());
            }
            // 识别 "i"
            if (state == 401) {
                // 识别 "if"
                if (symbol == 'f') {
                    temp.append(symbol);
                    this.inputPointer++;
                    return new TwoTuple("if", temp.toString());
                }
                if (symbol >= 'a' && symbol <= 'z') {
                    state = 1;
                    temp.append(symbol);
                    this.inputPointer++;
                    continue;
                }
                state = 1;
                continue;
            }
            // 识别 "s"
            if (state == 201) {
                // 识别 "st"
                if (symbol == 't') {
                    state = 202;
                    temp.append(symbol);
                    this.inputPointer++;
                    continue;
                }
                if (symbol >= 'a' && symbol <= 'z') {
                    state = 1;
                    temp.append(symbol);
                    this.inputPointer++;
                    continue;
                }
                state = 1;
                continue;
            }
            // 识别 "st"
            if (state == 202) {
                // 识别 "str"
                if (symbol == 'r') {
                    state = 203;
                    temp.append(symbol);
                    this.inputPointer++;
                    continue;
                }
                // 识别 "sta"
                if (symbol == 'a') {
                    state = 303;
                    temp.append(symbol);
                    this.inputPointer++;
                    continue;
                }
                if (symbol >= 'a' && symbol <= 'z') {
                    state = 1;
                    temp.append(symbol);
                    this.inputPointer++;
                    continue;
                }
                state = 1;
                continue;
            }
            // 识别 "str"
            if (state == 203) {
                // 识别 "stri"
                if (symbol == 'i') {
                    state = 204;
                    temp.append(symbol);
                    this.inputPointer++;
                    continue;
                }
                if (symbol >= 'a' && symbol <= 'z') {
                    state = 1;
                    temp.append(symbol);
                    this.inputPointer++;
                    continue;
                }
                state = 1;
                continue;
            }
            // 识别 "stri"
            if (state == 204) {
                // 识别 "strin"
                if (symbol == 'n') {
                    state = 205;
                    temp.append(symbol);
                    this.inputPointer++;
                    continue;
                }
                if (symbol >= 'a' && symbol <= 'z') {
                    state = 1;
                    temp.append(symbol);
                    this.inputPointer++;
                    continue;
                }
                state = 1;
                continue;
            }
            // 识别 "strin"
            if (state == 205) {
                // 识别 "String"
                if (symbol == 'g') { // string
                    temp.append(symbol);
                    this.inputPointer++;
                    return new TwoTuple("string", temp.toString());
                }
                if (symbol >= 'a' && symbol <= 'z') {
                    state = 1;
                    temp.append(symbol);
                    this.inputPointer++;
                    continue;
                }
                state = 1;
                continue;
            }
            // 识别 "sta"
            if (state == 303) {
                // 识别 "star"
                if (symbol == 'r') {
                    state = 304;
                    temp.append(symbol);
                    this.inputPointer++;
                    continue;
                }
                if (symbol >= 'a' && symbol <= 'z') {
                    state = 1;
                    temp.append(symbol);
                    this.inputPointer++;
                    continue;
                }
                state = 1;
                continue;
            }
            // 识别 "star"
            if (state == 304) {
                // 识别 "start"
                if (symbol == 't') { // start
                    temp.append(symbol);
                    this.inputPointer++;
                    return new TwoTuple("start", temp.toString());
                }
                if (symbol >= 'a' && symbol <= 'z') {
                    state = 1;
                    temp.append(symbol);
                    this.inputPointer++;
                    continue;
                }
                state = 1;
                continue;
            }
            // 识别 "e"
            if (state == 501) {
                // 识别 "el"
                if (symbol == 'l') {
                    state = 502;
                    temp.append(symbol);
                    this.inputPointer++;
                    continue;
                }
                // 识别 "en"
                if (symbol == 'n') {
                    state = 602;
                    temp.append(symbol);
                    this.inputPointer++;
                    continue;
                }
                if (symbol >= 'a' && symbol <= 'z') {
                    state = 1;
                    temp.append(symbol);
                    this.inputPointer++;
                    continue;
                }
                state = 1;
                continue;
            }
            // 识别 "el"
            if (state == 502) {
                // 识别 "els"
                if (symbol == 's') {
                    state = 503;
                    temp.append(symbol);
                    this.inputPointer++;
                    continue;
                }
                if (symbol >= 'a' && symbol <= 'z') {
                    state = 1;
                    temp.append(symbol);
                    this.inputPointer++;
                    continue;
                }
                state = 1;
                continue;
            }
            // 识别 "els"
            if (state == 503) {
                // 识别 "else"
                if (symbol == 'e') { // else
                    temp.append(symbol);
                    this.inputPointer++;
                    return new TwoTuple("else", temp.toString());
                }
                if (symbol >= 'a' && symbol <= 'z') {
                    state = 1;
                    temp.append(symbol);
                    this.inputPointer++;
                    continue;
                }
                state = 1;
                continue;
            }
            // 识别 "en"
            if (state == 602) {
                // 识别 "end"
                if (symbol == 'd') { // end
                    temp.append(symbol);
                    this.inputPointer++;
                    return new TwoTuple("end", temp.toString());
                }
                if (symbol >= 'a' && symbol <= 'z') {
                    state = 1;
                    temp.append(symbol);
                    this.inputPointer++;
                    continue;
                }
                state = 1;
                continue;
            }
            // 识别 "d"
            if (state == 1001) {
                // 识别 "do"
                if (symbol == 'o') { // do
                    temp.append(symbol);
                    this.inputPointer++;
                    return new TwoTuple("do", temp.toString());
                }
                if (symbol >= 'a' && symbol <= 'z') {
                    state = 1;
                    temp.append(symbol);
                    this.inputPointer++;
                    continue;
                }
                state = 1;
                continue;
            }
            // 识别 "w"
            if (state == 1101) {
                // 识别 "wh"
                if (symbol == 'h') {
                    state = 1102;
                    temp.append(symbol);
                    this.inputPointer++;
                    continue;
                }
                if (symbol >= 'a' && symbol <= 'z') {
                    state = 1;
                    temp.append(symbol);
                    this.inputPointer++;
                    continue;
                }
                state = 1;
                continue;
            }
            // 识别 "wh"
            if (state == 1102) {
                // 识别 "whi"
                if (symbol == 'i') {
                    state = 1103;
                    temp.append(symbol);
                    this.inputPointer++;
                    continue;
                }
                if (symbol >= 'a' && symbol <= 'z') {
                    state = 1;
                    temp.append(symbol);
                    this.inputPointer++;
                    continue;
                }
                state = 1;
                continue;
            }
            // 识别 "whi"
            if (state == 1103) { // whi
                // 识别 "whil"
                if (symbol == 'l') {
                    state = 1104;
                    temp.append(symbol);
                    this.inputPointer++;
                    continue;
                }
                if (symbol >= 'a' && symbol <= 'z') {
                    state = 1;
                    temp.append(symbol);
                    this.inputPointer++;
                    continue;
                }
                state = 1;
                continue;
            }
            // 识别 "whil"
            if (state == 1104) { // whil
                // 识别 "while"
                if (symbol == 'e') { // while
                    temp.append(symbol);
                    this.inputPointer++;
                    return new TwoTuple("while", temp.toString());
                }
                if (symbol >= 'a' && symbol <= 'z') {
                    state = 1;
                    temp.append(symbol);
                    this.inputPointer++;
                    continue;
                }
                state = 1;
                continue;
            }

            if (symbol != '#' && symbol != '\r' && symbol != '\n' && symbol != 'Q') {
                temp.append(symbol);
                this.inputPointer++;

                return new TwoTuple("Error2", "未规定符号 " + temp);
            }
            temp.setLength(0);
            state = 0;
            inputPointer++;
        }
        return new TwoTuple("#", "#");
    }

    private boolean isExistMark(int inputPointer) { //找到匹配的引号

        inputPointer++;
        while (inputProgram[inputPointer] != '#') {

            if (inputProgram[inputPointer] == '"') {
                return true;
            }
            inputPointer++;
        }

        return false;
    }

    public boolean match(String type) throws IOException {
        if (type.equals(this.word.type)) {
            //匹配成功
            System.out.println(pre + "【语】文法：" + type + " 读头：" + this.word.type + "，匹配成功");
            output.append(pre + "【语】文法：" + type + " 读头：" + this.word.type + "，匹配成功\n");
            this.word = this.nextInput(this.inputProgram);
            System.out.println(pre + "【词】:下一个单词:" + "(" + this.word.type + ", " + this.word.value + ")");
            output.append(pre + "【词】:下一个单词:" + "(" + this.word.type + ", " + this.word.value + ")" + "\n");
            if (this.word.type.equals("#") && this.word.value.equals("#")) {
                System.out.println("词法分析结束");
            }

            return true;
        }

        System.out.println(pre + "【语】文法：" + type + " 读头：" + this.word.type + "，匹配失败");
        output.append(pre + "【语】文法：" + type + " 读头：" + this.word.type + "，匹配失败\n");

        return false;
    }

    // <程序> →<变量说明部分>;<语句部分> P->string I;G
    public boolean ParseProgram() throws IOException {
        pre.append("-");
        System.out.println(pre + "【DEBUG】开始处理<程序>->【<变量说明部分>】;<语句部分>");
        output.append(pre + "【DEBUG】开始处理<程序>->【<变量说明部分>】;<语句部分>\n");

        System.out.println(pre + "【语】<变量说明部分>->string<标识符列表>");
        output.append(pre + "【语】<变量说明部分>->string<标识符列表>\n");
        pre.append("-");
        System.out.println(pre + "【DEBUG】开始处理<变量说明部分>->【string】<标识符列表>");
        output.append(pre + "【DEBUG】开始处理<变量说明部分>->【string】<标识符列表>\n");

        boolean bl;
        bl = match("string");
        if (!bl) {
            System.out.println("语法分析错误，强制结束");
            output.append("语法分析错误，强制结束\n");
            // 文件写入
            return false;
        }

        System.out.println(pre + "【DEBUG】开始处理<变量说明部分>->string【<标识符列表>】");
        output.append(pre + "【DEBUG】开始处理<变量说明部分>->string【<标识符列表>】\n");
        bl = ParseIdentifierList("string");
        if (!bl) {
            System.out.println("语法分析错误，强制结束");
            output.append("语法分析错误，强制结束\n");
            // 文件写入
            return false;
        }

        System.out.println(pre + "【done】<变量说明部分>->string<标识符列表>,处理成功");
        output.append(pre + "【done】<变量说明部分>->string<标识符列表>,处理成功");

        pre.deleteCharAt(pre.length() - 1);

        System.out.println(pre + "【DEBUG】开始处理<程序>-><变量说明部分>【;】<语句部分>");
        output.append(pre + "【DEBUG】开始处理<程序>-><变量说明部分>【;】<语句部分>\n");

        bl = match("分号");
        if (!bl) {
            System.out.println("语法分析错误，强制结束");
            output.append("语法分析错误，强制结束\n");
            // 文件写入
            return false;
        }
        System.out.println(pre + "【DEBUG】开始处理<程序>-><变量说明部分>;【<语句部分>】");
        output.append(pre + "【DEBUG】开始处理<程序>-><变量说明部分>;【<语句部分>】\n");

        bl = ParseStatementSection();
        if (!bl) {
            System.out.println("语法分析错误，强制结束");
            output.append("语法分析错误，强制结束\n");
            // 文件写入
            return false;
        }

        System.out.println(pre + "【DEBUG】<程序>-><变量说明部分>;<语句部分>，处理成功");
        output.append(pre + "【DEBUG】<程序>-><变量说明部分>;<语句部分>，处理成功\n");
        pre.deleteCharAt(pre.length() - 1);
        System.out.println("语法分析结束\n");
        output.append(pre + "语法分析结束\n");

        return true;
    }

    public boolean ParseIdentifierList(String type) throws IOException {
        System.out.println(pre + "【语】<标识符列表>-><标识符><标识符列表prime>");
        output.append(pre + "【语】<标识符列表>-><标识符><标识符列表prime>\n");
        pre.append("-");
        System.out.println(pre + "【DEBUG】开始处理<标识符列表>-><标识符><标识符列表prime>");
        output.append(pre + "【DEBUG】开始处理<标识符列表>-><标识符><标识符列表prime>\n");

        String name = word.value;
        match("标识符");
        identifierTable.add(name);
        identifierTable.updateIdentifierTypeByName(name, type);

        System.out.println(pre + "【翻】填写标识符" + name + " 类型为 " + type);
        output.append(pre + "【翻】填写标识符" + name + " 类型为 " + type + "\n");

        System.out.println(pre + "【DEBUG】开始处理<标识符列表>-><标识符>【<标识符列表prime>】");
        output.append(pre + "【DEBUG】开始处理<标识符列表>-><标识符>【<标识符列表prime>】\n");
        ParseIdentifierListPrime(type);
        System.out.println(pre + "【done】<标识符列表>-><标识符><标识符列表prime>，处理成功");
        output.append(pre + "【done】<标识符列表>-><标识符><标识符列表prime>，处理成功\n");

        pre.deleteCharAt(pre.length() - 1);

        return true;
    }

    //	I'->,iI'|$
    public boolean ParseIdentifierListPrime(String type) throws IOException {
        if (word.type.equals("逗号")) {
            System.out.println(pre + "【语】选择<标识符列表prime> ->，<标识符><标识符列表prime>");
            output.append(pre + "【语】选择<标识符列表prime> ->，<标识符><标识符列表prime>\n");
            pre.append("-");
            System.out.println(pre + "【DEBUG】开始处理<标识符列表prime> ->【，】<标识符><标识符列表prime>");
            output.append(pre + "【DEBUG】开始处理<标识符列表prime> ->【，】<标识符><标识符列表prime>\n");

            match("逗号");
            String name = word.value;
            System.out.println(pre + "【DEBUG】开始处理<标识符列表prime> ->，【<标识符>】<标识符列表prime>");
            output.append(pre + "【DEBUG】开始处理<标识符列表prime> ->，【<标识符>】<标识符列表prime>\n");

            match("标识符");
//            identifierTable.add(word.value);
            identifierTable.add(name);

            System.out.println(pre + "【翻】填写标识符" + name + "类型为 " + type);
            output.append(pre + "【翻】填写标识符" + name + "类型为 " + type + "\n");

            identifierTable.updateIdentifierTypeByName(name, type);
            System.out.println(pre + "【DEBUG】开始处理<标识符列表>-><标识符>【<标识符列表prime>】");
            output.append(pre + "【DEBUG】开始处理<标识符列表>-><标识符>【<标识符列表prime>】");
            // Ip(type);
            ParseIdentifierListPrime(type);
            System.out.println(pre + "【done】<标识符列表>-><标识符><标识符列表prime>，处理成功");
            output.append(pre + "【done】<标识符列表>-><标识符><标识符列表prime>，处理成功\n");
            pre.deleteCharAt(pre.length() - 1);

            return true;
        }
        if (word.type.equals("分号")) {
            //	I'->$
            pre.append("-");
            System.out.println(pre + "【语】选择<标识符列表prime> ->空串");
            output.append(pre + "【语】选择<标识符列表prime> ->空串\n");
            System.out.println(pre + "【done】选择<标识符列表prime> ->空串，处理成功");
            output.append(pre + "【done】选择<标识符列表prime> ->空串，处理成功\n");
            pre.deleteCharAt(pre.length() - 1);

            return true;
        }

        return false;
    }

    // G->S;G'
    public boolean ParseStatementSection() throws IOException {
        System.out.println(pre + "【语】<语句部分> -><语句>;<语句部分prime>");
        output.append(pre + "【语】<语句部分> -><语句>;<语句部分prime>\n");
        pre.append("-");
        System.out.println(pre + "【DEBUG】开始处理<语句部分> ->【<语句>】;<语句部分prime>");
        output.append(pre + "【DEBUG】开始处理<语句部分> ->【<语句>】;<语句部分prime>\n");
        // S();
        ParseStatement();

        System.out.println(pre + "【DEBUG】开始处理<语句部分> -><语句>【;】<语句部分prime>");
        output.append(pre + "【DEBUG】开始处理<语句部分> -><语句>【;】<语句部分prime>\n");
        match("分号");
        System.out.println(pre + "【DEBUG】开始处理<语句部分> -><语句>;【<语句部分prime>】");
        output.append(pre + "【DEBUG】开始处理<语句部分> -><语句>;【<语句部分prime>】\n");
        // GP();
        ParseStatementSectionPrime();

        System.out.println(pre + "【done】开始处理<语句部分> -><语句>;<语句部分prime>");
        output.append(pre + "【done】开始处理<语句部分> -><语句>;<语句部分prime>\n");
        pre.deleteCharAt(pre.length() - 1);

        return true;
    }

    // G'->S;G'|$
    public boolean ParseStatementSectionPrime() throws IOException {
        if (word.type.equals("标识符") || word.type.equals("if") || word.type.equals("do")) {
            System.out.println(pre + "【语】选择<语句部分prime> →<语句>;<语句部分prime>");
            output.append(pre + "【语】选择<语句部分prime> →<语句>;<语句部分prime>\n");
            pre.append("-");
            System.out.println(pre + "【DEBUG】选择<语句部分prime> →【<语句>】;<语句部分prime>");
            output.append(pre + "【DEBUG】选择<语句部分prime> →【<语句>】;<语句部分prime>\n");

            ParseStatement();
            System.out.println(pre + "【DEBUG】选择<语句部分prime> →<语句>【;】<语句部分prime>");
            output.append(pre + "【DEBUG】选择<语句部分prime> →<语句>【;】<语句部分prime>\n");

            match("分号");
            System.out.println(pre + "【DEBUG】选择<语句部分prime> →<语句>;【<语句部分prime>】");
            output.append(pre + "【DEBUG】选择<语句部分prime> →<语句>;【<语句部分prime>】\n");

            ParseStatementSectionPrime();
            System.out.println(pre + "【done】选择<语句部分prime> →<语句>;<语句部分prime>");
            output.append(pre + "【done】选择<语句部分prime> →<语句>;<语句部分prime>\n");
            pre.deleteCharAt(pre.length() - 1);

            return true;
        }
        if (word.type.equals("#") || word.type.equals("end")) {
            // I->$
            pre.append("-");
            System.out.println(pre + "【语】选择<语句部分prime> →空串");
            output.append(pre + "【语】选择<语句部分prime> →空串\n");
            System.out.println(pre + "【done】选择<语句部分prime> →空串,处理成功");
            output.append(pre + "【done】选择<语句部分prime> →空串，处理成功\n");
            pre.deleteCharAt(pre.length() - 1);

            return true;
        }

        return false;
    }

    // S->A|C|R
    public boolean ParseStatement() throws IOException {
//        System.out.println(pre + "【语】选择<语句>→<赋值语句>|<条件语句>|<循环语句>");
        if (word.type.equals("标识符")) {
            System.out.println(pre + "【语】选择<语句>→<赋值语句>");
            output.append(pre + "【语】选择<语句>→<赋值语句>\n");
            pre.append("-");
            System.out.println(pre + "【DEBUG】开始处理<语句>->【<赋值语句>】");
            output.append(pre + "【DEBUG】开始处理<语句>->【<赋值语句>】\n");
            ParseAssignStatement();
            System.out.println(pre + "【done】<语句>-><赋值语句>,处理成功");
            output.append(pre + "【done】<语句>-><赋值语句>,处理成功\n");
            pre.deleteCharAt(pre.length() - 1);

            return true;
        }
        if (word.type.equals("if")) {
            System.out.println(pre + "【语】选择<语句>→<条件语句>");
            output.append(pre + "【语】选择<语句>→<条件语句>\n");
            pre.append("-");
            System.out.println(pre + "【DEBUG】开始处理<语句>->【<条件语句>】");
            output.append(pre + "【DEBUG】开始处理<语句>->【<条件语句>】\n");

            ParseIfStatement();
            System.out.println(pre + "【done】<语句>-><条件语句>,处理成功");
            output.append(pre + "【done】<语句>-><条件语句>,处理成功\n");
            pre.deleteCharAt(pre.length() - 1);

            return true;
        }
        if (word.type.equals("do")) {
            System.out.println(pre + "【语】选择<语句>→<循环语句>");
            output.append(pre + "【语】选择<语句>→<循环语句>\n");
            pre.append("-");
            System.out.println(pre + "【DEBUG】开始处理<语句>->【<循环语句>】");
            output.append(pre + "【DEBUG】开始处理<语句>->【<循环语句>】\n");

            ParseDoStatement();
            System.out.println(pre + "【done】<语句>-><循环语句>,处理成功");
            output.append(pre + "【done】<语句>-><循环语句>,处理成功\n");
            pre.deleteCharAt(pre.length() - 1);

            return true;
        }

        return false;
    }

    // A->i=E
    public boolean ParseAssignStatement() throws IOException {
        System.out.println(pre + "【语】<赋值语句>-><标识符>=<表达式>");
        output.append(pre + "【语】<赋值语句>-><标识符>=<表达式>\n");
        pre.append("-");
        String name = word.value;
        System.out.println(pre + "【DEBUG】开始处理<赋值语句>->【<标识符>】=<表达式>");
        output.append(pre + "【DEBUG】开始处理<赋值语句>->【<标识符>】=<表达式>\n");

        match("标识符");
        System.out.println(pre + "【翻】获取赋值语句标识符" + name);
        output.append(pre + "【翻】获取赋值语句标识符\n");
        System.out.println(pre + "【DEBUG】开始处理<赋值语句>-><标识符>【=】<表达式>");
        output.append(pre + "【DEBUG】开始处理<赋值语句>-><标识符>【=】<表达式>\n");

        match("=");
        System.out.println(pre + "【DEBUG】开始处理<赋值语句>-><标识符>=【<表达式>】");
        output.append(pre + "【DEBUG】开始处理<赋值语句>-><标识符>=【<表达式>】\n");

        Identifier E = ParseExpression();
        identifierTable.updateIdentifierValueByName(name, E.getValue());
        System.out.println(pre + "【翻】更新标识符" + name + "值为" + E.getValue());
        output.append(pre + "【翻】更新标识符" + name + "值为" + E.getValue() + "\n");

        codeTable.add("=", E.getName(), "null", name);
        System.out.println(pre + "【翻】生成赋值语句四元式");
        output.append(pre + "【翻】生成赋值语句四元式\n");
        System.out.println(pre + "【done】<赋值语句>-><标识符>=<表达式>,处理成功");
        output.append(pre + "【done】<赋值语句>-><标识符>=<表达式>,处理成功\n");
        pre.deleteCharAt(pre.length() - 1);

        return true;
    }

    // C->if (L) Q else
    public boolean ParseIfStatement() throws IOException {
        System.out.println(pre + "【语】<条件语句>->if(<条件>)<嵌套语句>else <嵌套语句>");
        output.append(pre + "【语】<条件语句>->if(<条件>)<嵌套语句>else <嵌套语句>\n");
        pre.append("-");
        System.out.println(pre + "【DEBUG】开始处理<条件语句>->【if】(<条件>)<嵌套语句>else <嵌套语句>");
        output.append(pre + "【DEBUG】开始处理<条件语句>->【if】(<条件>)<嵌套语句>else <嵌套语句>\n");

        match("if");
        System.out.println(pre + "【DEBUG】开始处理<条件语句>->if【(】<条件>)<嵌套语句>else <嵌套语句>");
        output.append(pre + "【DEBUG】开始处理<条件语句>->if【(】<条件>)<嵌套语句>else <嵌套语句>\n");

        match("左括号");
        System.out.println(pre + "【DEBUG】开始处理<条件语句>->if(【<条件>】)<嵌套语句>else <嵌套语句>");
        output.append(pre + "【DEBUG】开始处理<条件语句>->if(【<条件>】)<嵌套语句>else <嵌套语句>\n");

        Identifier E = ParseLogicExpression();
        System.out.println(pre + "【翻】产生if语句真出口跳转四元式");
        output.append(pre + "【翻】产生if语句真出口跳转四元式\n");
        codeTable.add("jnz", E.name, "null", String.valueOf(codeTable.getNXQ() + 2));

        System.out.println(pre + "【翻】产生if语句假出口跳转四元式");
        output.append(pre + "【翻】产生if语句假出口跳转四元式\n");
        codeTable.add("j", "null", "null", "0");    //要回填

        System.out.println(pre + "【DEBUG】开始处理<条件语句>->if(<条件>【)】<嵌套语句>else <嵌套语句>");
        output.append(pre + "【DEBUG】开始处理<条件语句>->if(<条件>【)】<嵌套语句>else <嵌套语句>\n");
        match("右括号");
        System.out.println(pre + "【DEBUG】开始处理<条件语句>->if(<条件>)【<嵌套语句>】else <嵌套语句>");
        output.append(pre + "【DEBUG】开始处理<条件语句>->if(<条件>)【<嵌套语句>】else <嵌套语句>\n");

        ParseNestedStatement();
        System.out.println(pre + "【翻】产生if语句出口跳转四元式");
        output.append(pre + "【翻】产生if语句出口跳转四元式\n");
        codeTable.add("j", "null", "null", "0");    //要回填

        System.out.println(pre + "【翻】回填if语句假出口地址");
        output.append(pre + "【翻】回填if语句假出口地址\n");
        int falseExitIndex = codeTable.getNXQ();
        codeTable.backPath(falseExitIndex, String.valueOf(codeTable.getNXQ()));

        System.out.println(pre + "【DEBUG】开始处理<条件语句>->if(<条件>)<嵌套语句>【else】 <嵌套语句>");
        output.append(pre + "【DEBUG】开始处理<条件语句>->if(<条件>)<嵌套语句>【else】 <嵌套语句>\n");
        match("else");
        System.out.println(pre + "【DEBUG】开始处理<条件语句>->if(<条件>)<嵌套语句>else【<嵌套语句>】");
        output.append(pre + "【DEBUG】开始处理<条件语句>->if(<条件>)<嵌套语句>else【<嵌套语句>】\n");

        ParseNestedStatement();
        System.out.println(pre + "【翻】回填if语句出口地址");
        output.append(pre + "【翻】回填if语句出口地址\n");
        int ExitIndex = codeTable.getNXQ();
        codeTable.backPath(ExitIndex, String.valueOf(codeTable.getNXQ()));

        System.out.println(pre + "【done】<条件语句>->if(<条件>)<嵌套语句>else <嵌套语句>，处理成功");
        output.append(pre + "【done】<条件语句>->if(<条件>)<嵌套语句>else <嵌套语句>，处理成功\n");

        pre.deleteCharAt(pre.length() - 1);

//        codeTable.add("jnz", E.name, "null", String.valueOf(codeTable.getNXQ() + 2));
////        int falseExitIndex = codeTable.getNXQ();
//        codeTable.add("j", "null", "null", "0");    //要回填
//        ParseNestedStatement();
//        int exitIndex = codeTable.getNXQ();
//        codeTable.add("j", "null", "null", "0");    //要回填
//        codeTable.backPath(falseExitIndex, String.valueOf(codeTable.getNXQ()));
//
//        match("else");
//        ParseNestedStatement();
//        codeTable.backPath(exitIndex, String.valueOf(codeTable.getNXQ()));
        return true;
    }

    public boolean ParseDoStatement() throws IOException {
        System.out.println(pre + "【语】<循环语句>->do<嵌套语句>while(<条件>)");
        output.append(pre + "【语】<循环语句>->do<嵌套语句>while(<条件>)\n");

        System.out.println(pre + "【DEBUG】开始处理<循环语句>->【do】<嵌套语句>while(<条件>)");
        output.append(pre + "【DEBUG】开始处理<循环语句>->【do】<嵌套语句>while(<条件>)\n");
        match("do");
        int Next = codeTable.getNXQ();
        System.out.println(pre + "【DEBUG】开始处理<循环语句>->do【<嵌套语句>】while(<条件>)");
        output.append(pre + "【DEBUG】开始处理<循环语句>->do【<嵌套语句>】while(<条件>)\n");

        ParseNestedStatement();

        System.out.println(pre + "【DEBUG】开始处理<循环语句>->do<嵌套语句>【while】(<条件>)");
        output.append(pre + "【DEBUG】开始处理<循环语句>->do<嵌套语句>【while】(<条件>)\n");
        match("while");
        System.out.println(pre + "【DEBUG】开始处理<循环语句>->do<嵌套语句>while【(】<条件>)");
        output.append(pre + "【DEBUG】开始处理<循环语句>->do<嵌套语句>while【(】<条件>)\n");

        System.out.println(pre + "【DEBUG】开始处理<循环语句>->do<嵌套语句>while【(】<条件>)");
        output.append(pre + "【DEBUG】开始处理<循环语句>->do<嵌套语句>while【(】<条件>)\n");
        match("左括号");

        System.out.println(pre + "【DEBUG】开始处理<循环语句>->do<嵌套语句>while【(】<条件>)");
        output.append(pre + "【DEBUG】开始处理<循环语句>->do<嵌套语句>while【(】<条件>)\n");

        Identifier E = ParseLogicExpression();
        codeTable.add("jnz", E.name, "null", String.valueOf(Next));
        System.out.println(pre + "【翻】产生while语句跳转四元式");
        output.append(pre + "【翻】产生while语句跳转四元式\n");


        System.out.println(pre + "【DEBUG】开始处理<循环语句>->do<嵌套语句>while(<条件【)】");
        output.append(pre + "【DEBUG】开始处理<循环语句>->do<嵌套语句>while(<条件>【)】\n");
        match("右括号");
        System.out.println(pre + "【done】<循环语句>->do<嵌套语句>while(<条件>),处理成功");
        output.append(pre + "【done】<循环语句>->do<嵌套语句>while(<条件>),处理成功\n");

        pre.deleteCharAt(pre.length() - 1);
//        match("while");
//        match("左括号");
//        int nextIndex = codeTable.getNXQ();
//        Identifier E = ParseLogicExpression();
//        match("右括号");
//        match("do");
//        codeTable.add("jnz", E.name, "null", String.valueOf(codeTable.getNXQ() + 2));
//        int falseExitIndex = codeTable.getNXQ();
//        codeTable.add("j", "null", "null", "0");    //要回填
//        ParseNestedStatement();
//        codeTable.add("j", "null", "null", String.valueOf(nextIndex));
//        codeTable.backPath(falseExitIndex, String.valueOf(codeTable.getNXQ()));
        return true;
    }

    // E->FE'
    public Identifier ParseExpression() throws IOException {
        System.out.println(pre + "【语】<表达式>-><项><表达式prime>");
        output.append(pre + "【语】<表达式>-><项><表达式prime>\n");
        pre.append("-");
        System.out.println(pre + "【DEBUG】开始处理<表达式>->【<项>】<表达式prime>");
        output.append(pre + "【DEBUG】开始处理<表达式>->【<项>】<表达式prime>\n");

        Identifier F1 = ParseItem();
        System.out.println(pre + "【DEBUG】开始处理<表达式>-><项>【<表达式prime>】");
        output.append(pre + "【DEBUG】开始处理<表达式>-><项>【<表达式prime>】\n");

        Identifier EP1 = ParseExpressionPrime(F1);
        System.out.println(pre + "【done】<表达式>-><项><表达式prime>，处理成功");
        output.append(pre + "【done】<表达式>-><项><表达式prime>，处理成功\n");
        pre.deleteCharAt(pre.length() - 1);

        return EP1;
    }

    // E'->+FE'|$
    public Identifier ParseExpressionPrime(Identifier E1) throws IOException {
        if (word.type.equals("连接运算符")) {
            System.out.println(pre + "【语】选择<表达式prime>-><连接运算符><项><表达式prime>");
            output.append(pre + "【语】选择<表达式prime>-><连接运算符><项><表达式prime>\n");
            pre.append("-");
            System.out.println(pre + "【DEBUG】开始处理<表达式prime>->【<连接运算符>】<项><表达式prime>");
            output.append(pre + "【DEBUG】开始处理<表达式prime>->【<连接运算符>】<项><表达式prime>\n");

            match("连接运算符");
            System.out.println(pre + "【DEBUG】开始处理<表达式prime>-><连接运算符>【<项>】<表达式prime>");
            output.append(pre + "【DEBUG】开始处理<表达式prime>->【<连接运算符>】<项><表达式prime>\n");

            Identifier E2 = ParseItem();
            System.out.println(pre + "【翻】创建加法运算临时变量");
            output.append(pre + "【翻】创建加法运算临时变量\n");

            Identifier T = tempVarTable.getNewTempVar();
            T.type = "string";
            try {
                T.value = String.valueOf(E1.getValue() + E2.getValue());
                System.out.println(pre + "【临时变量表】加法运算临时变量：（" + T.type + "," + T.value + "）");
                output.append(pre + "【临时变量表】加法运算临时变量：（" + T.type + "," + T.value + "）\n");
            } catch (NumberFormatException e) {
                e.printStackTrace();
            }

            codeTable.add("+", E1.getName(), E2.getName(), T.name);
            System.out.println(pre + "【翻】产生加法运算四元式");
            output.append(pre + "【翻】产生加法运算四元式\n");

            System.out.println(pre + "【DEBUG】开始处理<表达式prime>-><连接运算符><项>【<表达式prime>】");
            output.append(pre + "【DEBUG】开始处理<表达式prime>-><连接运算符><项>【<表达式prime>】\n");
            Identifier EP1 = ParseExpressionPrime(T);
            System.out.println(pre + "【done】<表达式prime>-><连接运算符><项><表达式prime>，处理成功");
            output.append(pre + "【done】<表达式prime>-><连接运算符><项><表达式prime>，处理成功\n");
            pre.deleteCharAt(pre.length() - 1);

            return EP1;
        }
        if (word.type.equals("else") || word.type.equals("while") || word.type.equals("分号") || word.type.equals("关系运算符") || word.type.equals("右括号")) {
            pre.append("-");
            System.out.println(pre + "【语】选择<表达式prime>->空串");
            output.append(pre + "【语】选择<表达式prime>->空串\n");
            System.out.println(pre + "【done】<表达式prime>->空串,处理成功");
            output.append(pre + "【done】<表达式prime>->空串,处理成功\n");
            pre.deleteCharAt(pre.length() - 1);

            return E1;
        }
        return E1;
    }

    //F->DF'
    public Identifier ParseItem() throws IOException {
        System.out.println(pre + "【语】<项>-><因子><项Prime>");
        output.append(pre + "【语】<项>-><因子><项Prime>");
        pre.append("-");
        Identifier F1 = new Identifier("");
        System.out.println(pre + "【DEBUG】开始处理<项>->【<因子>】<项Prime>");
        output.append(pre + "【DEBUG】开始处理<项>->【<因子>】<项Prime>\n");

        F1 = ParseYinzi();

        System.out.println(pre + "【DEBUG】开始处理<项>-><因子>【<项Prime>】");
        output.append(pre + "【DEBUG】开始处理<项>-><因子>【<项Prime>】\n");
        F1 = ParseItemPrime(F1);
        System.out.println(pre + "【done】<项>-><因子><项Prime>,处理成功");
        output.append(pre + "【done】<项>-><因子><项Prime>,处理成功");

        return F1;
    }

    //F'->*nF'|$
    public Identifier ParseItemPrime(Identifier F1) throws IOException {
        System.out.println(pre + "【DEBUG】发现多条产生式");
        output.append(pre + "【DEBUG】发现多条产生式\n");

        if (word.type.equals("重复运算符")) {
            System.out.println(pre + "【DEBUG】开始处理<项Prime>->【<重复运算符>】<数字><项Prime>");
            output.append(pre + "【DEBUG】开始处理<项Prime>->【<重复运算符>】<数字><项Prime>\n");
            pre.append("-");
            System.out.println(pre + "【DEBUG】发现多条产生式");
            output.append(pre + "【DEBUG】发现多条产生式\n");

            match("重复运算符");
            int n = Integer.parseInt(word.value);
            System.out.println(pre + "【DEBUG】开始处理<项Prime>-><重复运算符>【<数字>】<项Prime>");
            output.append(pre + "【DEBUG】开始处理<项Prime>-><重复运算符>【<数字>】<项Prime>\n");

            ConstTable.put(String.valueOf(n), "数字");
            match("数字");

            System.out.println(pre + "【翻】创建乘法运算临时变量");
            output.append(pre + "【翻】创建乘法运算临时变量\n");
            Identifier T = tempVarTable.getNewTempVar();
            T.value = "";
            T.type = "string";
            for (int i = 0; i < n; i++) {
                T.value = T.value + F1.value;
            }
            System.out.println(pre + "【临时变量表】乘法运算临时变量：（" + T.type + "," + T.value + "）");
            output.append(pre + "【临时变量表】乘法运算临时变量：（" + T.type + "," + T.value + "）\n");
            System.out.println(pre + "【翻】产生乘法运算四元式");
            output.append(pre + "【翻】产生乘法运算四元式\n");
            codeTable.add("*", F1.getName(), String.valueOf(n), T.name);

            Identifier FP1 = new Identifier("");
            System.out.println(pre + "【DEBUG】开始处理<项Prime>-><重复运算符><数字>【<项Prime>】");
            output.append(pre + "【DEBUG】开始处理<项Prime>-><重复运算符><数字>【<项Prime>】\n");
            FP1 = ParseItemPrime(T);
            System.out.println(pre + "【done】<项Prime>-><重复运算符><数字><项Prime>，处理成功");
            output.append(pre + "【done】<项Prime>-><重复运算符><数字><项Prime>，处理成功\n");
            pre.deleteCharAt(pre.length() - 1);

            return FP1;
        }
        if (word.type.equals("连接运算符") || word.type.equals("else") || word.type.equals("while") || word.type.equals("分号") || word.type.equals("关系运算符") || word.type.equals("右括号")) {
            pre.append("-");
            System.out.println(pre + "【翻】产生乘法运算四元式");
            output.append(pre + "【翻】产生乘法运算四元式\n");
            System.out.println(pre + "【翻】产生乘法运算四元式");
            output.append(pre + "【翻】产生乘法运算四元式\n");
            pre.deleteCharAt(pre.length() - 1);

            return F1;
        }

        return F1;
    }

    //  D->i|s|(E)
    public Identifier ParseYinzi() throws IOException {
        Identifier E = new Identifier("");
        if (word.type.equals("标识符")) {
            System.out.println(pre + "【语】选择<因子>-><标识符>");
            output.append(pre + "【语】选择<因子>-><标识符>\n");
            pre.append("-");
            String name = word.value;
            match("标识符");
            System.out.println(pre + "【翻】获取标识符值" + name);
            output.append(pre + "【翻】获取标识符值" + name + "\n");


            E = new Identifier(name);
            E.value = identifierTable.getIdentifierValueByName(name);
            System.out.println(pre + "【done】<因子>-><标识符>，处理成功");
            output.append(pre + "【done】<因子>-><标识符>，处理成功\n");
            pre.deleteCharAt(pre.length() - 1);

            return E;
        }
        if (word.type.equals("字符串")) {
            System.out.println(pre + "【语】选择<因子>-><字符串>");
            output.append(pre + "【语】选择<因子>-><字符串>\n");
            pre.append("-");

            System.out.println(pre + "【翻】创建字符串的临时变量");
            output.append(pre + "【翻】创建字符串的临时变量\n");
            E = new Identifier(word.value);
            E.value = word.value;
            E.type = "string";
            match("字符串");
            System.out.println(pre + "【临时变量表】字符串临时变量：（" + E.type + "," + E.value + "）");
            output.append(pre + "【临时变量表】字符串临时变量：（" + E.type + "," + E.value + "）\n");
            ConstTable.put(E.value, E.type);


            System.out.println(pre + "【done】<因子>-><字符串>，处理成功");
            output.append(pre + "【done】<因子>-><字符串>，处理成功\n");
            pre.deleteCharAt(pre.length() - 1);

            return E;
        }
        if (word.type.equals("左括号")) {
            System.out.println(pre + "【语】选择<因子>->（<表达式>）");
            output.append(pre + "【语】选择<因子>->（<表达式>）\n");
            pre.append("-");
            System.out.println(pre + "【DEBUG】开始处理<因子>->【（】<表达式>）");
            output.append(pre + "【【DEBUG】开始处理<因子>->【（】<表达式>）\n");
            match("左括号");
            System.out.println(pre + "【DEBUG】开始处理<因子>->（【<表达式>】）");
            output.append(pre + "【【DEBUG】开始处理<因子>->（【<表达式>】）\n");

            E = ParseExpression();
            System.out.println(pre + "【DEBUG】开始处理<因子>->（<表达式>【）】");
            output.append(pre + "【【DEBUG】开始处理<因子>->（<表达式>【）】\n");
            match("右括号");

            System.out.println(pre + "【done】<因子>->（<表达式>）,处理成功");
            output.append(pre + "【done】<因子>->（<表达式>）,处理成功\n");
            pre.deleteCharAt(pre.length() - 1);

            return E;
        }
        exit(0);
        return E;
    }

    // L->E j E
    public Identifier ParseLogicExpression() throws IOException {
        System.out.println(pre + "【语】<条件>-><表达式><关系运算符><表达式>");
        output.append(pre + "【语】<条件>-><表达式><关系运算符><表达式>\n");
        pre.append("-");

        System.out.println(pre + "【DEBUG】开始处理<条件>->【<表达式>】<关系运算符><表达式>");
        output.append(pre + "【DEBUG】开始处理<条件>->【<表达式>】<关系运算符><表达式>\n");
        Identifier E1 = ParseExpression();
        System.out.println(pre + "【DEBUG】开始处理<条件>-><表达式>【<关系运算符>】<表达式>");
        output.append(pre + "【DEBUG】开始处理<条件>-><表达式>【<关系运算符>】<表达式>\n");
//        identifierName = E1.name;
//        value1 = Integer.parseInt(E1.value);


        String logicOperator = word.value;
        match("关系运算符");
        System.out.println(pre + "【DEBUG】开始处理<条件>-><表达式><关系运算符>【<表达式>】");
        output.append(pre + "【DEBUG】开始处理<条件>-><表达式><关系运算符>【<表达式>】\n");
        Identifier E2 = ParseExpression();

        System.out.println(pre + "【翻】创建关系运算临时变量");
        output.append(pre + "【翻】创建关系运算临时变量\n");

        Identifier T = tempVarTable.getNewTempVar();
        T.type = "bool";
        System.out.println(pre + "【临时变量表】关系运算临时变量：（" + T.type + "," + T.value + "）");
        output.append(pre + "【临时变量表】关系运算临时变量：（" + T.type + "," + T.value + "）\n");
        codeTable.add(logicOperator, E1.name, E2.name, T.name);

        System.out.println(pre + "【翻】产生关系(" + logicOperator + ")运算四元式");
        output.append(pre + "【翻】产生关系(" + logicOperator + ")运算四元式\n");
        System.out.println(pre + "【done】<条件>-><表达式><关系运算符><表达式>,处理成功");
        output.append(pre + "【done】<条件>-><表达式><关系运算符><表达式>,处理成功\n");
        pre.deleteCharAt(pre.length() - 1);

        return T;
    }

    // B->start G end
    public boolean ParseCompoundStatement() throws IOException {
        System.out.println(pre + "【语】<复合语句>->start<语句部分>end");
        output.append(pre + "【语】<复合语句>->start<语句部分>end\n");
        pre.append("-");
        System.out.println(pre + "【DEBUG】开始处理<复合语句>->【start】<语句部分>end");
        output.append(pre + "【DEBUG】开始处理<复合语句>->【start】<语句部分>end\n");
        match("start");
        System.out.println(pre + "【DEBUG】开始处理<复合语句>->start【<语句部分>】end");
        output.append(pre + "【DEBUG】开始处理<复合语句>->start【<语句部分>】end\n");

        ParseStatementSection();

        System.out.println(pre + "【DEBUG】开始处理<复合语句>->start<语句部分>【end】");
        output.append(pre + "【DEBUG】开始处理<复合语句>->start<语句部分>【end】\n");
        match("end");
        System.out.println(pre + "【done】<复合语句>->start<语句部分>end,处理成功");
        output.append(pre + "【done】<复合语句>->start<语句部分>end,处理成功\n");
        pre.deleteCharAt(pre.length() - 1);

        return true;
    }

    // Q->S|B
    public boolean ParseNestedStatement() throws IOException {
        if (word.type.equals("标识符") || word.type.equals("if") || word.type.equals("do")) {

            System.out.println(pre + "【语】选择<嵌套语句>-><语句>");
            output.append(pre + "【语】选择<嵌套语句>-><语句>\n");
            pre.append("-");
            System.out.println(pre + "【DEBUG】开始处理<嵌套语句>->【<语句>】");
            output.append(pre + "【DEBUG】开始处理<嵌套语句>->【<语句>】\n");
            ParseStatement();
            System.out.println(pre + "【done】<嵌套语句>-><语句>,处理成功");
            output.append(pre + "【done】<嵌套语句>-><语句>,处理成功\n");
            pre.deleteCharAt(pre.length() - 1);

            return true;
        }
        if (word.type.equals("start")) {
            System.out.println(pre + "【语】选择<嵌套语句>-><语句>");
            output.append(pre + "【语】选择<嵌套语句>-><语句>\n");
            pre.append("-");
            System.out.println(pre + "【DEBUG】开始处理<嵌套语句>->【<复合语句>】");
            output.append(pre + "【DEBUG】开始处理<嵌套语句>->【<复合语句>】\n");
            ParseCompoundStatement();
            System.out.println(pre + "【done】<嵌套语句>-><复合语句>,处理成功");
            output.append(pre + "【done】<嵌套语句>-><复合语句>,处理成功\n");
            pre.deleteCharAt(pre.length() - 1);

            return true;
        }

        return false;
    }
}
